package routes

import (
	"github.com/garyburd/redigo/redis"
	"github.com/martini-contrib/render"
	"log"
	"net/http"
	"rhelper"
	"strconv"
	"strings"
)

func GetFarms(r render.Render, req *http.Request) {
	var a = req.URL.Query().Get("a")
	var farmId = req.URL.Query().Get("farmId")
	conn := rhelper.Pool().Get()
	defer conn.Close()

	type Farm struct {
		Name string `json:"name"`
		Id   string `json:"id"`
	}

	var farms []Farm = nil
	var farmIdArray []string
	var i int = 0
	farmIds, err := redis.String(conn.Do("HGET", rhelper.AccountHash+a, "farms"))
	if err != nil {
		log.Println("get farms err:", err)
	}

	if farmIds == "" || err != nil {
		log.Println("no farms configure for account:", a)
		goto OUT
	}

	if strings.Contains(farmIds, ",") {
		farmIdArray = strings.Split(farmIds, ",")
	} else {
		farmIdArray = []string{farmIds}
	}

	farms = make([]Farm, len(farmIdArray))

	for _, id := range farmIdArray {
		fields, err := redis.Strings(conn.Do("HMGET", rhelper.FarmHash+id, "id", "name"))
		if err == nil && fields[0] != "" {
			var f = &farms[i]
			f.Id = fields[0]
			f.Name = fields[1]
			i++
		}
	}

	farms = farms[0:i]
OUT:
	r.HTML(200, "farmMgr", TmplValue{Title: "Account manange", ExtValue: farms, ExtValue2: farmId, ExtValue3: a})
}

func GetFarmInfo(r render.Render, req *http.Request) {
	var farmId = req.URL.Query().Get("farmId")
	conn := rhelper.Pool().Get()
	defer conn.Close()

	type Farm struct {
		Err         string `json:"err"`
		Name        string `json:"name"`
		Id          string `json:"id"`
		Description string `json:"description"`
		Account     string `json:"account"`

		Controllers []string `json:"controllers"`
	}

	var farm Farm = Farm{}
	farmInfos, err := redis.Strings(conn.Do("HMGET", rhelper.FarmHash+farmId, "name", "id", "description", "account", "controllers"))
	if err != nil {
		farm.Err = err.Error()
		r.JSON(200, farm)
		return
	}

	if len(farmInfos) < 1 || farmInfos[0] == "" {
		farm.Err = "not found farm:" + farmId
		r.JSON(200, farm)
		return
	}

	farm.Name = farmInfos[0]
	farm.Id = farmInfos[1]
	farm.Description = farmInfos[2]
	farm.Account = farmInfos[3]

	var controllers []string
	if strings.Contains(farmInfos[4], ",") {
		controllers = strings.Split(farmInfos[4], ",")
	} else {
		controllers = []string{farmInfos[4]}
	}

	farm.Controllers = controllers

	r.JSON(200, farm)
}

func EditFarm(r render.Render, req *http.Request) {
	var farmId = req.URL.Query().Get("farmId")
	var account = req.URL.Query().Get("a")
	conn := rhelper.Pool().Get()
	defer conn.Close()

	if farmId == "" || account == "" {
		r.Error(404)
		return
	}

	type Farm struct {
		Id          string
		Account     string
		Name        string
		Description string
		IsNew       bool
	}

	var farm Farm = Farm{}

	if farmId == "newFarm" {
		newId, _ := redis.Int(conn.Do("INCR", rhelper.FarmIdHolder))
		farm.IsNew = true
		farm.Id = strconv.FormatInt(int64(newId), 10)
		farm.Account = account
	} else {
		farm.IsNew = false
		fields, err := redis.Strings(conn.Do("HMGET", rhelper.FarmHash+farmId, "id", "account", "name", "description"))
		if err != nil {
			log.Println(err)
		}
		farm.Id = fields[0]
		farm.Account = fields[1]
		farm.Name = fields[2]
		farm.Description = fields[3]
	}

	r.HTML(200, "farmEdit", TmplValue{Title: "farm edit", ExtValue: farm})
}

type FarmEditValue struct {
	Id          string `form:"textinput-farmId" json:"id,omitempty"`
	Account     string `form:"textinput-farmAccount" json:"account,omitempty"`
	Name        string `form:"textinput-farmName" json:"name,omitempty"`
	Description string `form:"textinput-farmDesc" json:"description,omitempty"`
}

func SaveFarm(farmValue FarmEditValue) string {
	var account = farmValue.Account
	var id = farmValue.Id
	var name = farmValue.Name
	var description = farmValue.Description

	conn := rhelper.Pool().Get()
	defer conn.Close()

	farms, _ := redis.String(conn.Do("HGET", rhelper.AccountHash+account, "farms"))
	if len(farms) < 1 {
		farms = id
	} else {
		if !commaStringContain(farms, id) {
			farms = farms + "," + id
		}
	}

	conn.Send("MULTI")
	conn.Send("HMSET", rhelper.FarmHash+id,
		"id", id, "account", account, "name", name, "description", description)
	conn.Send("HSET", rhelper.AccountHash+account, "farms", farms)
	_, err := conn.Do("EXEC")
	if err != nil {
		log.Println(err)
		return err.Error()
	}

	return "ok"
}

func AddFarmController(r render.Render, req *http.Request) {
	var farmId = req.URL.Query().Get("farmId")
	var account = req.URL.Query().Get("a")

	if farmId == "" || account == "" {
		r.Error(404)
		return
	}

	type Farm struct {
		Id      string
		Account string
	}

	var farm Farm = Farm{Id: farmId, Account: account}

	r.HTML(200, "farmControllerAdd", TmplValue{Title: "farm edit", ExtValue: farm})
}

func CheckFarmController(r render.Render, req *http.Request) string {
	var controllerId = req.URL.Query().Get("textinput-farmController")

	conn := rhelper.Pool().Get()
	defer conn.Close()

	id, err := redis.String(conn.Do("HGET", rhelper.ControllerHash+controllerId, "id"))
	if err != nil {
		log.Println(err)
		return err.Error()
	}

	if id == "" {
		return "controller " + controllerId + " not exists"
	}

	return "true"
}

type FarmControllerEditValue struct {
	Id           string `form:"textinput-farmId" json:"id,omitempty"`
	Account      string `form:"textinput-farmAccount" json:"account,omitempty"`
	ControllerId string `form:"textinput-farmController" json:"controller,omitempty"`
}

func SaveFarmController(farmValue FarmControllerEditValue) string {
	id := farmValue.Id
	//account := farmValue.Account
	controllerId := farmValue.ControllerId

	conn := rhelper.Pool().Get()
	defer conn.Close()

	controllers, err := redis.String(conn.Do("HGET", rhelper.FarmHash+id, "controllers"))
	if err != nil {
		return err.Error()
	}

	if len(controllers) > 0 {
		if !commaStringContain(controllers, controllerId) {
			controllers = controllers + "," + controllerId
		}
	} else {
		controllers = controllerId
	}

	_, err = conn.Do("HSET", rhelper.FarmHash+id, "controllers", controllers)
	if err != nil {
		return err.Error()
	}

	return "ok"
}

func DelFarmControllers(req *http.Request) string {
	err := req.ParseForm()
	if err != nil {
		log.Println(err)
		return err.Error()
	}

	conn := rhelper.Pool().Get()
	defer conn.Close()

	var farmId = req.Form.Get("farmId")
	var ids = req.Form.Get("ids")
	var idarray []string
	if strings.Contains(ids, ",") {
		idarray = strings.Split(ids, ",")
	} else {
		idarray = []string{ids}
	}

	controllers, err := redis.String(conn.Do("HGET", rhelper.FarmHash+farmId, "controllers"))
	var controllersArray []string
	if strings.Contains(controllers, ",") {
		controllersArray = strings.Split(controllers, ",")
	} else {
		controllersArray = []string{controllers}
	}

	newControllersArray := make([]string, len(controllersArray))
	var newControllerIndex = 0
	for _, a := range controllersArray {
		var deleted bool = false
		for _, b := range idarray {
			if a == b {
				deleted = true
				break
			}
		}

		if !deleted {
			newControllersArray[newControllerIndex] = a
			newControllerIndex++
		}
	}

	newControllersArray = newControllersArray[0:newControllerIndex]
	newControllers := ""
	if len(newControllersArray) > 0 {
		newControllers = newControllersArray[0]
		for i := 1; i < len(newControllersArray); i++ {
			newControllers = newControllers + "," + newControllersArray[i]
		}
	}

	if len(newControllers) < 1 {
		_, _ = conn.Do("HDEL", rhelper.FarmHash+farmId, "controllers")
	} else {
		_, _ = conn.Do("HSET", rhelper.FarmHash+farmId, "controllers", newControllers)
	}
	return "ok"
}
